#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2021/4/22 14:45
# @Author  : hqu-jcl
# @Site    : 
# @File    : Filter.py

import cv2
import numpy as np
import copy
import math
import matplotlib.pyplot as plt
import skimage


def MeanFilter(image,k):
    """
      均值滤波
    :param image: 图片矩阵
    :return: 均值滤波后的图片
    """
    if k==1:
        template = np.ones([3, 3]) / 9
    elif k==2:
        template=np.array([[1,2,1],[2,4,2],[1,2,1]])/16
    else:
        pass
    image = np.array(image)
    result = copy.deepcopy(image)
    for i in range(len(image)):
        for j in range(len(image[0])):
            if (i - 1) >= 0 and (j - 1) >= 0 and (i + 1) < len(image) and (j + 1) < len(image[0]):
                result[i, j] = (template[0, 0] * image[i - 1, j - 1] + template[0, 1] * image[i - 1, j] +
                                template[0, 2] * image[i, j + 1] +

                                template[1, 0] * image[i, j - 1] + template[1, 1] * image[i, j] +
                                template[1, 2] * image[i, j + 1] +

                                template[2, 0] * image[i + 1, j - 1] + template[2, 1] * image[i + 1, j] +
                                template[2, 2] * image[i + 1, j + 1])

            else:
                pass
    return result


def MedianFilter(image):
    """
        中值滤波
    :param image: 需要处理的图像
    :return: 中值滤波后的图像
    """
    image = np.array(image)
    result = copy.deepcopy(image)
    for i in range(len(image)):
        for j in range(len(image[0])):
            if (i - 1) >= 0 and (j - 1) >= 0 and (i + 1) < len(image) and (j + 1) < len(image[0]):
                result[i, j] = (np.median([image[i - 1, j - 1], image[i - 1, j],
                                           image[i, j + 1],

                                           image[i, j - 1], image[i, j],
                                           image[i, j + 1],

                                           image[i + 1, j - 1], image[i + 1, j],
                                           image[i + 1, j + 1]]))
            else:
                pass
    return result


def cal_gradient(image):
    """
       计算梯度和梯度方向
    :param image: 图像
    :return:  梯度，梯度方向
    """
    template_x = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]])
    template_y = np.array([[-1, -2, -1], [0, 0, 0], [1, 2, 1]])
    image = np.array(image)
    result_gradient_x = copy.deepcopy(image)
    result_gradient_y = copy.deepcopy(image)
    result_gradient = copy.deepcopy(image)
    result_direction=np.zeros([len(image),len(image[0])-1])
    result_angle = copy.deepcopy(image)
    result_angle=result_angle.astype(np.float)
    for i in range(len(image)):
        for j in range(len(image[0])):
            if (i - 1) >= 0 and (j - 1) >= 0 and (i + 1) < len(image) and (j + 1) < len(image[0]):
                gradient_x = (
                            template_x[0, 0] * image[i - 1, j - 1] + template_x[0, 1] * image[i - 1, j] +
                            template_x[0, 2] * image[i, j + 1] +

                            template_x[1, 0] * image[i, j - 1] + template_x[1, 1] * image[i, j] +
                            template_x[1, 2] * image[i, j + 1] +

                            template_x[2, 0] * image[i + 1, j - 1] + template_x[2, 1] * image[i + 1, j] +
                            template_x[2, 2] * image[i + 1, j + 1])

                gradient_y = (
                        template_y[0, 0] * image[i - 1, j - 1] + template_y[0, 1] * image[i - 1, j] +
                        template_y[0, 2] * image[i, j + 1] +

                        template_y[1, 0] * image[i, j - 1] + template_y[1, 1] * image[i, j] +
                        template_y[1, 2] * image[i, j + 1] +

                        template_y[2, 0] * image[i + 1, j - 1] + template_y[2, 1] * image[i + 1, j] +
                        template_y[2, 2] * image[i + 1, j + 1])
                result_gradient_x[i,j]=gradient_x
                result_gradient_y[i,j]=gradient_y
                result_gradient[i, j] = np.sqrt(gradient_x ** 2 + gradient_y ** 2)
                result_angle[i, j] = np.arctan2(gradient_y,gradient_x)
                if result_angle[i,j]<0:
                    result_angle[i,j]+=2*np.pi
            else:
                pass

    for i in range(1,len(result_angle)-1):
        for j in range(1,len(result_angle[0])-1):
            result_direction[i-1,j-1]=result_angle[i,j]

    cv2.normalize(result_direction,result_direction,0,255,cv2.NORM_MINMAX)
    result_direction = result_direction.astype(dtype=np.uint8)
    return result_gradient, result_direction
    # return result_gradient_x,result_gradient_y


if __name__ == '__main__':
    img = cv2.imread('../resource/Fig0335.tif', 0)
    img_lena=cv2.imread("../resource/lena.jpg",0)
    # image_ = MedianFilter(img)
    # cv2.imshow('result', image_)
    # cv2.waitKey(0)
    # a=cv2.Sobel(img,-1,0,1)
    # cv2.imshow('temp',a)
    # cv2.waitKey(0)

    # image_1,image_2 = cal_gradient(img)
    # #image_2 = MeanFilter(img)
    # cv2.imshow("1", image_1)
    # cv2.waitKey(0)
    #
    # cv2.imshow("1", image_2)
    # cv2.waitKey(0)
    #
    img1 = MeanFilter(img,k=1)
    img2 = MeanFilter(img,k=2)
    img3 = MedianFilter(img)

    img4=cv2.subtract(img1,img)
    img5=cv2.subtract(img2,img)
    img6=cv2.subtract(img3,img)
    cv2.imshow("4", MeanFilter(img1,k=1))
    cv2.imshow("5", MeanFilter(img2,k=2))
    cv2.waitKey(0)

    # result1,result2=cal_gradient(img_lena)
    # # cv2.normalize(result2,result2,0,255,cv2.NORM_MINMAX)
    # cv2.imshow('gradient_x',result1)
    # cv2.imshow('gradient_y',result2)
    # cv2.waitKey(0)
    sobelx = cv2.Sobel(img_lena, cv2.CV_32F, 1, 0, ksize=3)
    sobely = cv2.Sobel(img_lena, cv2.CV_32F, 0, 1, ksize=3)
    direction = cv2.phase(sobelx, sobely, True)
    cv2.normalize(direction, direction, 0, 255, cv2.NORM_MINMAX)
    direction=np.array(direction).astype(np.uint8)
    plt.imshow(direction,'gray')
    plt.show()


    # cv2.waitKey(0)
